{$CLEO .cs}
{$USE CLEO+}
{$USE Audio}
{$USE newOpcodes}
{$USE ini}

0000: NOP

script_name "Security Van Heist"

// By ArtemQa146

if
    0AA2: 31@ = load_dynamic_library "CLEO+.cleo"
then
    if
        0AA4: 30@ = get_dynamic_library_procedure "GetCleoPlusVersion" library 31@
    then
        0AA7: call_function_return 30@ num_params 0 pop 0 29@
        if
            not 29@ >= 0x1020000
        then
            0AD1: show_formatted_text_highpriority "Cleo+ 1.2.0 (or higher) version is required, the Busy Pedestrians mod is disabled" time 15000
            0AA3: free_dynamic_library 31@
            0A93: terminate_this_custom_script
        end
        0AA3: free_dynamic_library 31@
    end
else
    0AD1: show_formatted_text_highpriority "Cleo+ 1.2.0 (or higher) version is required, the Busy Pedestrians mod is disabled" time 15000
    0AA3: free_dynamic_library 31@
    0A93: terminate_this_custom_script
end

0AF0: 0@ = read_int_from_ini_file "cleo\Busy Pedestrians.ini" section "Settings" key "Security Van Heist"
if
    0@ == 0
then
    0A93: terminate_this_custom_script
end

const
    find_car = 31@
    car_security = 0@
    check_damage = 30@
    intensity_damage = 29@
    Check_stay_player = 28@
    Case_money = 26@
    Security_Driver = 24@
    Security_second = 23@
    Render_model = 22@
    Find_obj = 31@
    Voice = 21@
    Memory_adr = 0xD // bool
    Memory_adr_obj = 0x10 // bool
    Memory_adr_dam = 0xE // dw
    Money_min = 6@
    Money_max = 5@
    Money_min_Stealth = 6@
    Money_max_Stealth = 5@
    Money_min_2 = 6@
    Money_max_2 = 5@
    Driver_WP_ID = 25@
    Driver_WP_Model = 19@
    Passenger_WP_ID = 18@
    Passenger_WP_Model = 17@
    Wanted_level_max = 27@
    Bit_sets = 11@
    Door_damage = 80.0
end

0AF0: Driver_WP_ID = read_int_from_ini_file "cleo\Busy Pedestrians.ini" section "Security Van Heist" key "Driver Weapon ID"
0AF0: Driver_WP_Model = read_int_from_ini_file "cleo\Busy Pedestrians.ini" section "Security Van Heist" key "Driver Weapon Model"

0AF0: Passenger_WP_ID = read_int_from_ini_file "cleo\Busy Pedestrians.ini" section "Security Van Heist" key "Passenger Weapon ID"
0AF0: Passenger_WP_Model = read_int_from_ini_file "cleo\Busy Pedestrians.ini" section "Security Van Heist" key "Passenger Weapon Model"

0AF0: Wanted_level_max = read_int_from_ini_file "cleo\Busy Pedestrians.ini" section "Security Van Heist" key "Maximum Wanted level"

if
    is_game_first_start
then
    0F00: load_special_model_dff "modelsq\Armored" txd "modelsq\OtherQa" store_to 0@
    0AF1: write_int 0@ to_ini_file "cleo\Security Van Heist.ini" section "Models" key "Armored"
end

0AF0: Render_model = read_int_from_ini_file "cleo\Security Van Heist.ini" section "Models" key "Armored"

Voice = -1
Check_stay_player = 0

while true
wait 20
    if
        player.Defined(0)
    then
        gosub @Remove_Voice

        //     ,   - 
        if and
            810F:   not player $PLAYER_CHAR wanted_level > 1
            00DF:   actor $PLAYER_ACTOR driving
        then
            03C0: car_security = actor $PLAYER_ACTOR car
            if
                0137:   car car_security model == 428
            then
                0A97: 4@ = car car_security struct
                0D4E: 4@ = struct 4@ offset Memory_adr size 1
                if
                    4@ == 2
                then
                    09B3: get_car car_security door_status 1@
                    if 1@ == 2
                    then 020A: set_car car_security door_status_to 1
                    end
                    2@ = 30.0 //  
                    
                    0E40: get_current_hour 1@
                    if or
                        1@ >= 22
                        1@ <= 5
                    then
                        2@ -= 18.0
                    end
                    
                    02E3: 1@ = car car_security speed
                    if
                        1@ > 30.0
                    then
                        2@ += 5.0
                    end

                    
                    0D59: get_current_weather_to 1@
                    if or
                        1@ == 8
                        1@ == 16
                    then
                        2@ -= 5.0
                    end

                    if
                        0EA5: get_closest_cop_near_char $PLAYER_ACTOR radius 2@ alive 1 in_car 1 on_foot 0 seen_in_front 1 store_to 3@
                    then
                        010E: set_player $PLAYER_CHAR minimum_wanted_level_to 2
                    end
                end
            end
        end
        
        find_car = 0
        while 0EA8: get_any_car_no_save_recursive find_car progress_to find_car car_to car_security
            if and
                0137:   car car_security model == 428
                not is_car_script_controlled car_security
            then
                0A97: 4@ = car car_security struct
                0D4E: 4@ = struct 4@ offset Memory_adr size 1
                if
                    4@ == 1 //       
                then
                    continue
                end

                gosub @Damage_Car
                
                //   
                046C: Security_Driver = car car_security driver
                if and
                    not Security_Driver == -1 //   
                    803B:   not Security_Driver == $PLAYER_ACTOR  // (int)
                then
                    //     
                    if
                        8491:   not actor Security_Driver has_weapon 31 //  
                    then
                        model.Load(Driver_WP_Model)
                        038B: load_requested_models
                        01B2: give_actor Security_Driver weapon Driver_WP_ID ammo 300 // Load the weapon model before using this
                        model.Destroy(Driver_WP_Model)
                        0F02:  Security_Driver special_model Render_model bone 3 offset 0.28 0.01 0 rotation 0 0 -4.5 scale 2@
                        0E37: set_render_object_scale 2@ 1.1 1.2 1.1
                        035F: actor Security_Driver armour += 100
                        060A: create_decision_maker_type 0 store_to 1@ // decision\allowed\m_.ped files
                        060B: set_actor Security_Driver decision_maker_to 1@
                        020A: set_car car_security door_status_to 2
                        081A: set_actor Security_Driver weapon_skill_to 2
                        0223: set_actor Security_Driver health_to 300
                    end
                    
                    //  

                    if
                        not is_char_exiting_any_car Security_Driver //   
                    then
                        0A97: 4@ = car car_security struct
                        0D4E: 4@ = struct 4@ offset Memory_adr size 1
                        if
                            not 4@ == 2 //         
                        then
                            model.Load(Passenger_WP_Model) // Chromegun
                            model.Load(71) // Security
                            038B: load_requested_models
                            01C8: Security_second = create_actor_pedtype 4 model 71 in_car car_security passenger_seat 0
                            01B2: give_actor Security_second weapon Passenger_WP_ID ammo 300 // Load the weapon model before using this
                            0F02:  Security_second special_model Render_model bone 3 offset 0.28 0.01 0 rotation 0 0 -4.5 scale 2@
                            0E37: set_render_object_scale 2@ 1.1 1.2 1.1
                            035F: actor Security_second armour += 100
                            01C2: remove_references_to_actor Security_second // Like turning an actor into a random pedestrian
                            if
                                056D:   actor Security_second defined // ..  01C2:    ,  .   
                            then
                                060A: create_decision_maker_type 0 store_to 1@ // decision\allowed\m_.ped files
                                060B: set_actor Security_second decision_maker_to 1@
                                0430: put_actor Security_second into_car car_security passenger_seat 0
                                081A: set_actor Security_second weapon_skill_to 2
                                0223: set_actor Security_second health_to 300
                            end
                            model.Destroy(71) // Security
                            model.Destroy(Passenger_WP_Model) // Chromegun
                            0A97: 4@ = car car_security struct
                            0E28: write_struct 4@ offset Memory_adr size 1 value 2 //    
                        end
                    end
                    
                    //    
                    if or
                        Actor.Animation($PLAYER_ACTOR) == "CAR_doorlocked_RHS" //     
                        Actor.Animation($PLAYER_ACTOR) == "CAR_doorlocked_LHS" // 
                    then
                        if
                            0EE5: locate_char_distance_to_car $PLAYER_ACTOR car car_security radius 4.0
                        then
                            gosub @Voice_Jack
                            gosub @Voice
                            010E: set_player $PLAYER_CHAR minimum_wanted_level_to 1
                            00AE: set_car car_security traffic_behaviour_to 2
                            00AD: set_car car_security max_speed_to 100.0
                        end
                    end

                    //         
                    if and
                        not check_damage == true
                        051C:   car car_security damaged_by_actor $PLAYER_ACTOR
                    then
                        gosub @Voice_Dam
                        gosub @Voice
                        0227: 1@ = car car_security health
                        if 1@ > 600
                        then 010E: set_player $PLAYER_CHAR minimum_wanted_level_to 1
                        else 010E: set_player $PLAYER_CHAR minimum_wanted_level_to 2
                        end
                        00AE: set_car car_security traffic_behaviour_to 2
                        00AD: set_car car_security max_speed_to 100.0
                        054F: clear_car car_security damage
                    end
                    
                    //       ,     
                    02E3: 1@ = car car_security speed
                    if and
                        not is_char_exiting_any_car Security_Driver
                        1@ < 3.0
                        check_damage == true
                    then
                        gosub @Voice_gun
                        gosub @Voice
                        gosub @Wanted_level
                        05E2: AS_actor Security_Driver kill_actor $PLAYER_ACTOR
                        if and
                            056D:   actor Security_second defined
                            Security_second > 0
                        then
                            05E2: AS_actor Security_second kill_actor $PLAYER_ACTOR
                        end
                        break
                    end
                    
                    //      
                    0E5B: get_car_dummy_coord car_security dummy 7 world_coords 0 invert_x 0 store_to 1@ 2@ 3@
                    2@ += 1.5
                    0407: store_coords_to 1@ 2@ 3@ from_car car_security with_offset 1@ 2@ 3@
                    if or
                        0EEA: locate_char_distance_to_coordinates $PLAYER_ACTOR pos 1@ 2@ 3@ radius 2.5
                        0547:   actor $PLAYER_ACTOR colliding_with_car car_security
                    then
                        if
                            Check_stay_player == 0
                        then
                            timerb = 0
                            Check_stay_player = 1
                        end
                        
                        if and
                            Check_stay_player == 1
                            timerb > 7000
                        then
                            gosub @Voice_Jack
                            gosub @Voice
                            00AE: set_car car_security traffic_behaviour_to 2
                            00AD: set_car car_security max_speed_to 100.0
                            timerb = 0
                            Check_stay_player = 0
                        end
                    end
                    //  
                    if and
                        timerb > 7500
                        Check_stay_player == 1
                    then
                        timerb = 0
                        Check_stay_player = 0
                    end
                    
                    //       
                    if and
                        not is_char_exiting_any_car Security_Driver //   
                        051A:   actor Security_Driver damaged_by_actor $PLAYER_ACTOR
                    then
                        gosub @Voice_gun
                        gosub @Voice
                        gosub @Wanted_level
                        if 8118:   not actor Security_Driver dead
                        then 05E2: AS_actor Security_Driver kill_actor $PLAYER_ACTOR
                        end
                        054E: clear_actor Security_Driver damage
                        if and
                            056D:   actor Security_second defined
                            Security_second > 0
                        then
                            if 8118:   not actor Security_second dead
                            then 05E2: AS_actor Security_second kill_actor $PLAYER_ACTOR
                            end
                        end
                        break
                    else
                        if and
                            not is_char_exiting_any_car Security_Driver //   
                            056D:   actor Security_second defined
                            Security_second > 0
                        then
                            if
                                051A:   actor Security_second damaged_by_actor $PLAYER_ACTOR
                            then
                                gosub @Voice_gun
                                gosub @Voice
                                gosub @Wanted_level
                                if 8118:   not actor Security_second dead
                                then 05E2: AS_actor Security_second kill_actor $PLAYER_ACTOR
                                end
                                054E: clear_actor Security_second damage
                                if 8118:   not actor Security_Driver dead
                                then 05E2: AS_actor Security_Driver kill_actor $PLAYER_ACTOR
                                end
                                break
                            end
                        end
                    end

                end

                //         
                if
                    check_damage == true
                then
                    check_damage = false

                    095F: get_car car_security door 4 angle_to 1@
                    095F: get_car car_security door 5 angle_to 2@
                    if or
                        1@ == 0.0
                        2@ == 0.0
                    then


                        if
                            0EE5: locate_char_distance_to_car $PLAYER_ACTOR car car_security radius 30.0
                        then
                            // 16@ -    
                            for 16@ = 0 to 1 Step 1
                                if 856E:   not car car_security defined
                                then break
                                end
                                gosub @Position_Shoot
                                for 15@ = 0.0 to 30.0 Step 1.0
                                wait 5
                                    if 856E:   not car car_security defined
                                    then break
                                    end
                                    0407: store_coords_to 2@ 3@ 4@ from_car car_security with_offset 12@ 13@ 14@
                                    0A9F: 5@ = current_thread_pointer
                                    000A: 5@ += 0x50
                                    0A8E: 6@ = 5@ + 0xC
                                    0AA6: call_method 0x514970 struct 0xB6F028 num_params 6 pop 0 6@ 5@ 4@ 3@ 2@ 15@
                                    050A: 1@ = distance_between_XYZ 2@ 3@ 4@ and_XYZ 8@ 9@ 10@
                                    if
                                        1@ < 1.0
                                    then
                                        04C4: store_coords_to 5@ 6@ 7@ from_actor $PLAYER_ACTOR with_offset 0.0 0.0 0.0
                                        if
                                            06BD:   no_obstacles_between 5@ 6@ 7@ and 2@ 3@ 4@ solid 1 car 1 actor 0 object 0 particle 0 //       
                                        then
                                            check_damage = true
                                            break
                                        end
                                    end
                                end
                            end
                        end

                        if
                            check_damage == true
                        then
                            if 856E:   not car car_security defined
                            then break
                            end
                            0A97: 1@ = car car_security struct
                            0D4E: 1@ = struct 1@ offset Memory_adr_dam size 4
                            005B: 1@ += intensity_damage  // (float)
                            0A97: 2@ = car car_security struct
                            0E28: write_struct 2@ offset Memory_adr_dam size 4 value 1@
                            if
                                1@ > Door_damage
                            then
                                gosub @Open_Door
                                break
                            end
                        end
                    end
                end

                if 856E:   not car car_security defined
                then break
                end

                //          
                095F: get_car car_security door 4 angle_to 1@
                095F: get_car car_security door 5 angle_to 2@
                if or
                    1@ <= 0.3
                    2@ <= 0.3
                then
                    0227: 1@ = car car_security health
                    if and
                        0EE5: locate_char_distance_to_car $PLAYER_ACTOR car car_security radius 30.0
                        1@ < 500
                    then
                        check_damage = false
                        gosub @Open_Door
                        break
                    end
                end

                //   
                095F: get_car car_security door 4 angle_to 1@
                095F: get_car car_security door 5 angle_to 2@
                if and
                    1@ <= -0.7
                    2@ >= 0.7
                then
                    check_damage = false
                    gosub @Open_Door
                    break
                end
                
                //   (   )
                if and
                    08A7:   car car_security componentB 4 opened_or_not_present
                    08A7:   car car_security componentB 5 opened_or_not_present
                then
                    check_damage = false
                    gosub @Open_Door
                    break
                end
            end
        end
    end
end

:Damage_Car
get_car_weapon_damage_last_frame car_security char 1@ type 2@ intensity intensity_damage
check_damage = false
if and
    003B:   1@ == $PLAYER_ACTOR  //   
    intensity_damage > 0.1
then
    check_damage = true
end
return

:Position_Shoot
0A97: 2@ = car car_security struct
0D4E: 2@ = struct 2@ offset 0x18 size 4
if 16@ == 0 //  for  
then 0AA7: call_function 0x4C5400 num_params 2 pop 2 "door_rr_dummy" 2@ 3@
else 0AA7: call_function 0x4C5400 num_params 2 pop 2 "door_lr_dummy" 2@ 3@
end
    if
        3@ <> 0
    then
        3@ += 0x10
        0D4E: 12@ = struct 3@ offset 0x30 size 4
        0D4E: 13@ = struct 3@ offset 0x34 size 4
        0D4E: 14@ = struct 3@ offset 0x38 size 4
        13@ -= 0.5
    else
        12@ = 0.0
        13@ = -3.0
        14@ = 1.0
    end
return

:Open_Door
4@ = 0.0
repeat
wait 0
    if
        056E:   car car_security defined
    then
        4@ += 0.05 //  
        08A6: set_car car_security door 4 rotation_to 4@
        08A6: set_car car_security door 5 rotation_to 4@
        if
            4@ > 0.9
        then
            //    
            
            16@ = 0
            gosub @Position_Shoot
            13@ -= 1.5
            0407: store_coords_to 4@ 5@ 6@ from_car car_security with_offset 12@ 13@ 14@
            02CE: 6@ = ground_z_at 4@ 5@ 6@
            6@ += 0.5
            
            0A97: 13@ = car car_security struct
            0D4E: 13@ = struct 13@ offset Memory_adr size 1
            if
                13@ == 0
            then
                0AF0: 2@ = read_int_from_ini_file "cleo\Busy Pedestrians.ini" section "Security Van Heist" key "Money Parked Min"
                0AF0: 3@ = read_int_from_ini_file "cleo\Busy Pedestrians.ini" section "Security Van Heist" key "Money Parked Max"
                0209: 14@ = random_int_in_ranges 2@ 3@
            else
                    if
                        010F:   player $PLAYER_CHAR wanted_level > 0
                    then
                        0AF0: 2@ = read_int_from_ini_file "cleo\Busy Pedestrians.ini" section "Security Van Heist" key "Money Default Min"
                        0AF0: 3@ = read_int_from_ini_file "cleo\Busy Pedestrians.ini" section "Security Van Heist" key "Money Default Max"
                        0209: 14@ = random_int_in_ranges 2@ 3@
                    else
                        0AF0: 2@ = read_int_from_ini_file "cleo\Busy Pedestrians.ini" section "Security Van Heist" key "Money Stealth Min"
                        0AF0: 3@ = read_int_from_ini_file "cleo\Busy Pedestrians.ini" section "Security Van Heist" key "Money Stealth Max"
                        0209: 14@ = random_int_in_ranges 2@ 3@
                    end
                end
            02E1: Case_money = create_cash_pickup 14@ at 4@ 5@ 6@ permanence_flag 0
            0E38: get_pickup_pointer Case_money store_to 1@
            1@ += 4 //   CObject
            0A8D: 1@ = read_memory 1@ size 4 virtual_protect 0
            0AEC: 2@ = object_struct 1@ handle
            08D2: object 2@ scale_model 0.0
            model.Load(1550)
            038B: load_requested_models
            0F03: create_render_object_to_object 2@ model 1550 offset 0 0 0 rotation 0 0 0 store_to 1@
            model.Destroy(1550)

            

            0A97: 4@ = car car_security struct
            0E28: write_struct 4@ offset Memory_adr size 1 value 1 //      

            if
                check_damage == true
            then
                //        ,    
                if and
                    803B:   not Security_second == $PLAYER_ACTOR  // (int)
                    056D:   actor Security_second defined
                    Security_second > 0
                then
                    if
                        00DB:   actor Security_second in_car car_security
                    then
                        05E2: AS_actor Security_second kill_actor $PLAYER_ACTOR
                        gosub @Wanted_level
                    end
                end
                if and
                    803B:   not Security_Driver == $PLAYER_ACTOR  // (int)
                    056D:   actor Security_Driver defined
                then
                    if
                        00DB:   actor Security_Driver in_car car_security
                    then
                        05E2: AS_actor Security_Driver kill_actor $PLAYER_ACTOR
                        gosub @Wanted_level
                    end
                end
            end
            break
        end
    else
        break
    end
until not player.Defined(0)
return

:Voice_gun
0209: 2@ = random_int_in_ranges 1 9
0AD3: 3@v = string_format "SQ\Gun%d.mp3" 2@
return

:Voice_Dam
0209: 2@ = random_int_in_ranges 1 7
0AD3: 3@v = string_format "SQ\Dam%d.mp3" 2@
return

:Voice_Jack
0209: 2@ = random_int_in_ranges 1 7
0AD3: 3@v = string_format "SQ\Jack%d.mp3" 2@
return

:Voice
if
    Voice == -1
then
    0AC1: Voice = load_audio_stream_with_3d_support 3@v // IF and SET
    0AC4: link_3d_audio_stream Voice to_actor Security_Driver
    0AAD: set_audio_stream Voice state 1
    0ABC: set_audio_stream Voice volume 1.0
    timera = 0
else
    gosub @Remove_Voice
end
return

:Remove_Voice
if and
    timera > 5000
    not Voice == -1
then
    0AAE: remove_audio_stream Voice
    Voice = -1
    timera = 0
end
return

:Wanted_level
0085: 2@ = Wanted_level_max // (int)
5@ = 0

//    
0E40: get_current_hour 1@
if or
    1@ >= 22
    1@ <= 5
then
    2@ -= 1 //  
    5@ += 1 //  
end

//  
08F7: get_player $PLAYER_CHAR bodypart 16 textureCRC_to 1@ modelCRC_to 3@ //  
08F7: get_player $PLAYER_CHAR bodypart 15 textureCRC_to 3@ modelCRC_to 4@ // /
if and
    1@ <> 0
    3@ <> 0
then
    2@ -= 1 //  
    5@ += 1 //  
end

if
    5@ >= 2
then
    if
        02D8:   actor $PLAYER_ACTOR current_weapon == 23 //    
    then
        2@ = 0
    else
        0D59: get_current_weather_to 1@
        if or
            1@ == 8
            1@ == 16
        then
            2@ = 0
        end
    end
end

//  = 3 
// +  = 2 
// +   = 2 
// +  +   = 1 
// +  +   +   / = 0 

010E: set_player $PLAYER_CHAR minimum_wanted_level_to 2@
return

